SideButton Marketing Website Knowledge Module
SideButton Marketing Website Solutions by Role — Knowledge Module Reference
SideButton Marketing Website knowledge module — UI selectors, data model, and page states documenting Solutions by Role.
sidebutton install SideButton Marketing Website - Path
- /solutions
- Verified
- 2026-02-21
- Confidence
- 95%
- Role playbooks
- 0
- Pack
- SideButton Marketing Website
- Domain
- sidebutton.com
What This Is
Solutions section -- browse AI-powered browser automations organized by professional role. Three-level page hierarchy: index (all roles grid + popular automations), role detail (hero + jobs list + platforms + category workflows), and job detail (tier badge + workflow card + sibling jobs). Data comes from an SQLite database (marketplace.db) via lib/marketplace.ts which exposes getRoles(), getJobs(), getJobsByRole(), getPlatform(), getWorkflow(), and getCategory(). Pages are statically generated at build time using Astro's getStaticPaths(). Every page includes JSON-LD structured data (BreadcrumbList, CollectionPage) for SEO.
URL Patterns
| Pattern | Description |
|---|---|
/solutions | Solutions index -- all roles grid sorted by automation count, popular automations list, cross-link to integrations, bottom CTA |
/solutions/{role} | Role detail -- breadcrumb, hero with title/headline/description, "What You Can Automate" jobs list, richSummary prose, target platforms grid, category workflows cards, bottom CTA |
/solutions/{role}/{job} | Job detail -- 3-level breadcrumb, tier badge + parent role link, job hero, "Available On" platforms, linked workflow card with "How it works" steps, usage chart, sibling jobs, bottom CTA |
Page Structure
Solutions Index (/solutions)
+--[Header: sticky banner]---------------------------+
| |
| [Hero: "Solutions by Role"] |
| Subtitle + 2 stat counters (roles, automations) |
| |
| [Browse by Role: 3-column card grid] |
| 11 role cards, each: |
| - title + headline + automation count/badge |
| - sorted by automation count (most first) |
| - "Coming soon" badge if 0 automations |
| |
| [Popular Automations: list] |
| Up to 6 items with workflow, each: |
| - bolt icon + title + role name + platform icons |
| - TierBadge (Free/Pro) + chevron arrow |
| |
| [Cross-link: "Looking for a specific platform?"] |
| Prose + "View all integrations" dark button |
| -> /integrations |
| |
| [CTA: "Ready to Automate Your Workflow?"] |
| Dark card with Get Started Free + See Pricing |
| |
+--[Footer: 6-column grid]---------------------------+
Role Detail (/solutions/{role})
+--[Header]------------------------------------------+
| |
| [Breadcrumb: Solutions > {Role Title}] |
| <nav> with <ol>, "/" separators |
| |
| [Hero: white card with blur accent] |
| H1: role.title (e.g. "Recruiting with ...") |
| Headline paragraph + description paragraph |
| Get Started Free (green) + See Pricing (outline) |
| |
| [What You Can Automate: job cards list] |
| Each: bolt icon + title + tagline |
| Platform icons (logo or color initial) + TierBadge|
| If 0 jobs: "Coming soon" empty state card |
| |
| [Rich Summary: prose paragraphs] (conditional) |
| role.richSummary split on double-newline |
| |
| [Target Platforms: icon grid] (conditional) |
| 2/4/6 columns, logo or color-initial + name |
| Each links to /integrations/{platform} |
| |
| [{Category} Workflows: card grid] (conditional) |
| Header with "Browse all {cat} integrations ->" |
| Up to 6 cards: title + TierBadge + tagline |
| "+ N more workflows ->" link if > 6 |
| |
| [CTA: "Ready to automate {role}?"] |
| Dark card with Get Started Free + See Pricing |
| |
+--[Footer]------------------------------------------+
Job Detail (/solutions/{role}/{job})
+--[Header]------------------------------------------+
| |
| [Breadcrumb: Solutions > {Role} > {Job}] |
| 3-level <nav> with <ol>, "/" separators |
| |
| [Hero: white card with blur accent] |
| TierBadge + "Part of {role.title}" link |
| H1: job.title |
| Headline (optional) + description (optional) |
| "View Workflow Details" green button (if workflow) |
| |
| [Available On: platform icon grid] (conditional) |
| Same layout as role target platforms |
| |
| [Workflow: linked card] (conditional) |
| Platform logo + title + tagline + description |
| "How it works" numbered step list |
| Entire card is a link to /integrations/{p}/{wf} |
| |
| [WorkflowRunChart: usage chart] (conditional) |
| Client-side chart component for the workflow slug |
| |
| [Other {Role} Automations: sibling job list] |
| Same card style as "What You Can Automate" |
| Excludes current job |
| |
| [CTA: "Automate this job today"] |
| Get Started Free + View Workflow Details |
| |
+--[Footer]------------------------------------------+
Key Elements
Solutions Index
| Element | Selector | Notes |
|---|---|---|
| Hero heading | main h1 / text "Solutions by Role" | H1, text-4xl md:text-5xl font-bold text-slate-900 |
| Roles stat counter | .flex.flex-wrap.gap-6 strong:first-of-type | Dynamic count from roles.length |
| Automations stat counter | .flex.flex-wrap.gap-6 strong:last-of-type | Dynamic count from totalJobs |
| Stat icon containers | .w-8.h-8.rounded-lg.bg-primary\/10 | Green-tinted icon backgrounds |
| Browse by Role heading | section h2 / text "Browse by Role" | text-xl font-bold text-slate-900 |
| Roles grid container | .grid.grid-cols-1.md\:grid-cols-2.lg\:grid-cols-3.gap-4 | 1/2/3 columns responsive |
| Role card | a.bg-white.rounded-xl.border.border-slate-200.p-6 | Links to /solutions/{slug} |
| Role card title | a h3.font-semibold | Strips " with SideButton AI" suffix from role.title |
| Role card headline | a p.text-sm.text-slate-600.line-clamp-2 | Truncated to 2 lines |
| Role automation count | span.text-sm.font-medium.text-primary | e.g., "3 automations" -- only when jobCount > 0 |
| Role coming soon badge | span.text-sm.text-slate-400 / text "Coming soon" | When jobCount === 0 |
| Role card chevron | a svg.w-4.h-4.text-slate-400 | Right arrow, turns primary on hover |
| Popular Automations heading | h2 / text "Popular Automations" | Only rendered if featuredJobs.length > 0 |
| Popular automation card | .grid.gap-3 > a.flex | Flex row with icon, title, role name, platforms, tier, chevron |
| Platform icon (logo) | img.w-5.h-5.rounded.object-contain | Uses platform.logoUrl |
| Platform icon (fallback) | div.w-5.h-5.rounded with inline background-color | First letter of platform name |
| Tier badge | TierBadge component | "Free" (emerald) or "Pro" (purple) pill |
| Cross-link section | div.bg-white.rounded-xl.border with heading + button | "Looking for a specific platform?" |
| View all integrations button | a.px-5.py-2\.5.bg-slate-900.text-white | Dark button -> /integrations |
| CTA section | div.bg-slate-900.rounded-2xl.p-8.md\:p-12.text-center | Dark card |
| Get Started Free (CTA) | a.bg-primary.text-white | -> https://docs.sidebutton.com/installation |
| See Pricing (CTA) | a.bg-white\/10.text-white | -> /pricing |
Role Detail
| Element | Selector | Notes |
|---|---|---|
| Breadcrumb nav | nav.max-w-6xl ol.flex | "Solutions / {Role Title}" |
| Breadcrumb Solutions link | nav a[href="/solutions"] | Links back to index |
| Current breadcrumb item | nav li.text-slate-900.font-medium | Non-linked current page |
| Hero card | section div.bg-white.rounded-2xl.border.p-8.md\:p-12 | White card with blur accent |
| Blur accent | div.absolute.w-96.h-96.bg-primary\/5.rounded-full.blur-3xl | Decorative gradient blob |
| Hero H1 | h1.text-3xl.md\:text-4xl.font-bold | role.title |
| Hero headline | p.text-xl.text-slate-600 | role.headline |
| Hero description | p.text-slate-500.mb-8 | role.description |
| Get Started Free button | a.bg-primary.text-white.font-semibold.rounded-xl | -> docs installation |
| See Pricing button | a.border-2.border-slate-200.text-slate-700.rounded-xl | -> /pricing |
| What You Can Automate heading | h2 / text "What You Can Automate" | Section heading |
| Job card | a.flex.items-center.justify-between.bg-white.rounded-xl | Links to /solutions/{role}/{job} |
| Job bolt icon | svg.w-5.h-5.text-slate-400 with lightning path | Turns primary on group hover |
| Job title | span.font-medium.text-slate-900 | job.title |
| Job tagline | p.text-xs.text-slate-500 | From workflow.marketing.tagline |
| Empty state card | div.bg-white.rounded-xl.text-center.text-slate-500 | "Coming soon" message when 0 jobs |
| Rich summary section | div.prose.prose-slate.max-w-none | Paragraphs from role.richSummary split on \n\n |
| Target Platforms heading | h2 / text "Target Platforms" | Only if platforms.length > 0 |
| Platform grid | .grid.grid-cols-2.md\:grid-cols-4.lg\:grid-cols-6.gap-4 | 2/4/6 columns responsive |
| Platform card | a.bg-white.rounded-xl.border.p-4.flex.flex-col.items-center | Logo + name, links to /integrations/{slug} |
| Platform logo | img.w-10.h-10.rounded-lg.object-contain | From platform.logoUrl |
| Platform color fallback | div.w-10.h-10.rounded-lg with inline color | First letter of name |
| Category Workflows heading | h2 / text "{Category} Workflows" | Only if matching category exists with workflows |
| Browse category link | a.text-sm.text-primary.font-medium | "Browse all {cat} integrations ->" |
| Workflow grid | .grid.gap-4.md\:grid-cols-2.lg\:grid-cols-3 | Up to 6 cards |
| Workflow card | a.bg-white.rounded-xl.border.p-6 | Title + TierBadge + tagline + platform pill |
| Platform pill in workflow card | span.inline-flex.px-2.py-1.text-xs.bg-slate-100.rounded-full | Platform logo + name |
| More workflows link | a.text-sm.text-primary / text "+ N more workflows ->" | Only if > 6 workflows |
| CTA heading | h2 / text containing "Ready to automate" | Dynamic text per role slug |
Job Detail
| Element | Selector | Notes |
|---|---|---|
| Breadcrumb nav | nav.max-w-6xl ol.flex | "Solutions / {Role} / {Job}" |
| Breadcrumb Solutions link | nav a[href="/solutions"] | First level |
| Breadcrumb Role link | nav a[href^="/solutions/"] (second link) | Links to parent role |
| Current breadcrumb item | nav li.text-slate-900.font-medium | Non-linked job title |
| Hero card | section div.bg-white.rounded-2xl.border.p-8.md\:p-12 | Same style as role hero |
| Tier badge in hero | TierBadge component (first child of flex row) | "Free" or "Pro" |
| Parent role link | a.text-primary[href^="/solutions/"] inside hero | "Part of {role.title}" |
| Job H1 | h1.text-3xl.md\:text-4xl.font-bold | job.title |
| Job headline | p.text-xl.text-slate-600 | Optional, job.headline |
| Job description | p.text-slate-500.mb-8 | Optional, job.description |
| View Workflow Details button | a.bg-primary.text-white.font-semibold.rounded-xl | Only if workflow exists, links to /integrations/{platform}/{slug} |
| Available On heading | h2 / text "Available On" | Only if platforms.length > 0 |
| Platform grid | .grid.grid-cols-2.md\:grid-cols-4.lg\:grid-cols-6.gap-4 | Same as role page |
| Workflow section heading | h2 / text "Workflow" | Only if workflow exists |
| Workflow card | a.block.bg-white.rounded-2xl.border.p-6 | Entire card is clickable link |
| Workflow platform logo | img.w-10.h-10.rounded-lg.object-contain.shrink-0 | From workflow's platform |
| Workflow title | h3.text-lg.font-semibold | workflow.title |
| Workflow tagline | p.text-slate-600.text-sm.mb-3 | workflow.marketing.tagline |
| Workflow description | p.text-slate-500.text-sm | workflow.marketing.description |
| How it works divider | div.mt-4.pt-4.border-t.border-slate-100 | Only if workflowSteps exist |
| How it works label | p.text-xs.font-medium.text-slate-500.uppercase | "How it works" |
| Step number circle | span.w-5.h-5.rounded-full.bg-primary\/10.text-primary.text-xs.font-bold | Numbered 1, 2, 3... |
| Step title | span inside li.flex | step.title |
| WorkflowRunChart | WorkflowRunChart component with slug prop | Client-side rendered usage chart |
| Other Automations heading | h2 / text "Other {Role} Automations" | Only if sibling jobs exist |
| Sibling job card | a.flex.items-center.justify-between.bg-white.rounded-xl | Same style as role job cards |
| CTA heading | h2 / text "Automate this job today" | Bottom CTA dark card |
| CTA description | p.text-slate-300 | "Install SideButton and start automating {job} ..." |
| Get Started Free (CTA) | a.bg-primary.text-white | -> docs installation |
| View Workflow Details (CTA) | a.bg-white\/10.text-white | Only if workflow, secondary button |
Data Model
Data is loaded from SQLite (marketplace.db) via lib/marketplace.ts. All tables are lazy-loaded and cached.
Role
| Field | Type | Description |
|---|---|---|
id | string | Unique role identifier (DB primary key) |
slug | string | URL-safe slug, e.g., recruiting, customer-support |
title | string | Display title, e.g., "Recruiting with SideButton AI" |
headline | string | One-line summary shown below title |
description | string | Longer description paragraph |
richSummary | string | Multi-paragraph prose, split on \n\n for rendering |
howItWorks | RoleStep[] | Array of { step, title, description, icon } (not currently rendered on solutions pages) |
seo.metaTitle | string | Page <title> tag |
seo.metaDescription | string | Meta description |
Job
| Field | Type | Description |
|---|---|---|
id | string | Unique job identifier |
slug | string | URL-safe slug, e.g., screen-resumes |
roleId | string | Foreign key to parent Role |
title | string | Display title, e.g., "Screen Resumes with AI" |
headline | string | Optional subtitle below H1 |
description | string | Optional longer description paragraph |
tier | 'free' | 'paid' | Pricing tier -- renders as "Free" (emerald) or "Pro" (purple) badge |
workflowSlug | string | null | Links to a Workflow; null if no workflow yet |
platforms | string[] | Array of platform slugs, e.g., ["linkedin", "greenhouse"] |
seo.metaTitle | string | Page <title> tag |
seo.metaDescription | string | Meta description |
sortOrder | number | Display ordering within the role (ascending) |
Platform (referenced)
| Field | Type | Description |
|---|---|---|
id | string | DB primary key |
slug | string | URL slug, e.g., linkedin, hubspot |
name | string | Display name, e.g., "LinkedIn" |
logoUrl | string | Path to logo image; empty string if none |
color | string | Hex color for fallback icon background |
Workflow (referenced)
| Field | Type | Description |
|---|---|---|
slug | string | Unique workflow slug |
title | string | Display title |
tier | 'free' | 'paid' | Pricing tier |
structural.platform | string | Platform slug; 'multi' for cross-platform |
structural.category | string | Category slug; matches role.slug for category workflow sections |
marketing.tagline | string | Short tagline |
marketing.description | string | Longer description |
marketing.workflowSteps | WorkflowStep[] | { step, title, description, icon } -- rendered as "How it works" on job detail |
Current Roles (11)
| Role | Slug | Automations | Status |
|---|---|---|---|
| Recruiting | recruiting | 3 | Active |
| Sales | sales | 1 | Active |
| Customer Support | customer-support | 0 | Coming soon |
| DevOps | devops | 0 | Coming soon |
| Personal Automation | personal-automation | 0 | Coming soon |
| Operations | operations | 0 | Coming soon |
| Marketing | marketing | 0 | Coming soon |
| Finance | finance | 0 | Coming soon |
| Research | research | 0 | Coming soon |
| HR & People Ops | hr-people-ops | 0 | Coming soon |
| AI Tools | ai-tools | 0 | Coming soon |
States & Variations
| State | Trigger | Visual Indicator |
|---|---|---|
| Index default | /solutions page load | All 11 role cards in 3-column grid, popular automations below |
| Role card with jobs | jobCount > 0 | Green text "{N} automation(s)" + primary-colored count |
| Role card coming soon | jobCount === 0 | Grey "Coming soon" text instead of count |
| Role card hover | Mouse over card | border-primary/50, shadow-md, title + chevron turn primary |
| Popular automation hover | Mouse over row | border-primary/50, shadow-sm, title + icons turn primary |
| Role detail default | /solutions/{role} load | Breadcrumb, hero, jobs list, platforms, category workflows |
| Role with 0 jobs | No jobs for role | "Coming soon -- workflows for this role are in development." center-aligned card |
| Role with richSummary | role.richSummary truthy | Prose paragraphs section rendered between jobs and platforms |
| Role without category workflows | No matching category or 0 workflows | Category Workflows section hidden entirely |
| Role with >6 category workflows | categoryWorkflows.length > 6 | "+ N more workflows ->" link below the grid |
| Job detail default | /solutions/{role}/{job} load | Breadcrumb, tier badge, hero, platforms, workflow card, siblings |
| Job without workflow | workflowSlug is null | "View Workflow Details" button hidden, Workflow section hidden, CTA shows only "Get Started Free" |
| Job without headline | job.headline falsy | Headline paragraph not rendered |
| Job without description | job.description falsy | Description paragraph not rendered |
| Job with 0 platforms | Empty platforms array | "Available On" section hidden |
| Job with 0 siblings | Only job in role | "Other {Role} Automations" section hidden |
| Workflow with steps | workflow.marketing.workflowSteps.length > 0 | "How it works" numbered list inside workflow card |
| Workflow without steps | No workflowSteps | Workflow card shows only title, tagline, description |
| Platform logo available | platform.logoUrl truthy | <img> tag with logo |
| Platform logo missing | platform.logoUrl empty | Colored <div> with first letter of platform name |
| TierBadge Free | tier === 'free' | Emerald pill: bg-emerald-100 text-emerald-700 with text "Free" |
| TierBadge Pro | tier === 'paid' | Purple pill: bg-purple-100 text-purple-700 with text "Pro" |
| Responsive 1-col | Viewport < md (768px) | Roles grid: 1 column; platform grid: 2 columns; CTA buttons stack vertically |
| Responsive 2-col | Viewport md-lg (768-1024px) | Roles grid: 2 columns; platform grid: 4 columns; workflow grid: 2 columns |
| Responsive 3-col | Viewport >= lg (1024px) | Roles grid: 3 columns; platform grid: 6 columns; workflow grid: 3 columns |
| Cookie dialog | First visit | Cookie Notice overlay |
| SideButton FAB | Extension installed | Green "S" + "Click" button bottom-right |
Common Tasks
-
Verify solutions index loads with all 11 roles: Navigate to
/solutions. Confirm the "Browse by Role" grid contains exactly 11 cards. Check that the stat counter shows "11" roles. Verify roles with jobs show the count (e.g., "3 automations") and roles without jobs show "Coming soon". -
Navigate from index to role detail: Click any role card on
/solutions. Verify the URL changes to/solutions/{role-slug}. Confirm breadcrumb shows "Solutions / {Role Title}". Verify H1 matches the role title and the hero contains headline + description + two CTA buttons. -
Navigate from role detail to job detail: On a role page with jobs (e.g.,
/solutions/recruiting), click a job card in "What You Can Automate". Verify URL is/solutions/{role}/{job}. Confirm 3-level breadcrumb. Check the tier badge (Free/Pro), parent role link text, and H1 job title. -
Verify breadcrumb navigation works at all levels: On a job detail page, click the "Solutions" breadcrumb link (should go to
/solutions). Go back, click the role breadcrumb link (should go to/solutions/{role}). Confirm both links resolve correctly. -
Check all platform badges render correctly: On a role page or job page with platforms, verify the platform grid section appears. Each platform should show either a logo image (
img.w-10.h-10) or a colored initial fallback (div.w-10.h-10). Click a platform card and verify it navigates to/integrations/{platform-slug}. -
Verify CTA links on all page levels: On each page level (index, role, job), check that "Get Started Free" links to
https://docs.sidebutton.com/installationand "See Pricing" links to/pricing. On job detail, verify "View Workflow Details" links to the correct/integrations/{platform}/{workflow}URL.
Tips
- The 3-level routing uses Astro's file-based routing:
solutions/index.astro,solutions/[role].astro, andsolutions/[role]/[job].astro. All paths are statically generated viagetStaticPaths(). - Role cards on the index strip the " with SideButton AI" and " with SideButton" suffixes from
role.titlefor cleaner display. The full title appears on the role detail H1. - The "Popular Automations" section on the index only shows jobs that have a
workflowSlug(filtered byj.workflowSlugtruthiness), limited to the first 6. - Platform icons use a two-tier rendering strategy:
<img>iflogoUrlexists, otherwise a colored<div>with the platform's first initial andbackground-colorfromplatform.color. - The category workflows section on role detail pages works by matching
role.slug === category.slugviagetCategory(role.slug). Only roles whose slug matches a category ID will show this section. - Workflow URLs on role and job pages are computed by checking
workflow.structural.platform: if it has a non-'multi'platform, the URL is/integrations/{platform}/{suffix}(stripping the platform prefix from the slug); otherwise it falls back to/integrations/categories/{category}/{slug}. - Every page includes JSON-LD structured data:
CollectionPage+BreadcrumbListon the index,BreadcrumbListon role and job pages. The index CollectionPage includes up to 10 roles asItemList. - The
RoleHero,RoleJobsList,RolePlatforms, andRoleStatscomponents exist as reusable Astro components but the role and job pages inline their own markup rather than using all of them.RoleStats(workflows/platforms/timeSaved counters) is not currently rendered on any solutions page. Role.howItWorksfield is loaded from thehow_it_worksJSON column in the DB but is NOT rendered on any solutions page currentlyJob.sortOrdercontrols the display ordering within a role — jobs are fetched withORDER BY sort_order ASCfrom SQLite, not alphabeticallyWorkflowRunCharton job detail loads uPlot 1.6.31 lazily from CDN (cdn.jsdelivr.net), not bundled — if CDN fails, chart silently doesn't renderWorkflowRunCharttooltip shows the raw internal run UUID to end users — potentially a UI/privacy concernWorkflowRunChartdata comes fromGET /api/runs/{slug}which returns{ runs: [], health: {} }with 60-second public cache- The workflow URL computation logic is duplicated 3 times (in
[role].astro,[job].astro, andRoleJobsList.astro) with slightly different fallback behavior — role page falls back to#, job page falls back to/integrations,RoleJobsListfalls back to/integrations getJobForWorkflow(workflowSlug)inmarketplace.tsprovides reverse lookup from workflow back to job — used by integrations workflow detail for the solutions cross-linkgetSameFunctionWorkflows()inmarketplace.tscontains hardcodedfunctionGroupsmapping cross-platform equivalents (e.g., Intercom/Zendesk/Freshdesk triage) but is NOT used on any solutions page
Gotchas
- Dynamic route 404s: If a role slug or job slug does not exist in the database, Astro will not generate the page and the URL returns 404. The
getStaticPaths()in[role].astromaps overgetRoles()and in[role]/[job].astromaps overgetJobs(), filtering out any job with no matching role (if (!role) return null). - Role title stripping is inconsistent: The index page strips " with SideButton AI" and " with SideButton" from card titles using
.replace(), but the role detail page shows the fullrole.titlein the H1. The breadcrumb also uses the full title. This means the same role may appear as "Recruiting" on the index but "Recruiting with SideButton AI" on the detail page. - Category workflows depend on slug matching: The category workflows section on role detail pages only appears when
getCategory(role.slug)finds a match. If the role slug and category slug diverge (e.g., a role is renamed), the section silently disappears with no error. - CTA text varies per role slug: The bottom CTA on role detail pages uses hardcoded slug checks (
role.slug === 'recruiting'/'sales') to customize the heading text. All other roles fall back to generic "your workflows" text. Adding a new role with jobs will show the generic text unless the template is updated. - Job detail "Other Automations" heading uses raw slug: The heading text for sibling jobs capitalizes the first letter of
role.slugdirectly (role.slug.charAt(0).toUpperCase() + role.slug.slice(1)), notrole.title. This produces "Other Recruiting Automations" but would produce "Other Customer-support Automations" for hyphenated slugs. - WorkflowRunChart on job detail only: The usage history chart component (
WorkflowRunChart) renders only on job detail pages and only when a workflow exists. The section isdisplay:noneat SSR; revealed client-side only if/api/runs/{slug}returns data. uPlot loaded from CDN; failure is silent. - WorkflowRunChart tooltip exposes run UUID: The chart tooltip shows the raw internal run UUID to end users — this is potentially unwanted information disclosure
- 3 duplicate URL computation implementations: Workflow URLs are computed in
[role].astro,[job].astro, andRoleJobsList.astrowith different fallback paths: role page falls back to#(broken link), job page falls back to/integrations(generic redirect),RoleJobsListfalls back to/integrations. A workflow withplatform: "multi"and no matching category will get different broken-link behavior depending on which page renders it. - Job.sortOrder is numeric ordering: Jobs within a role are displayed in
sortOrderascending order (from DB), not alphabetically — reordering requires a DB change - Index role count may differ from actual: The stat counter on
/solutionsshowsroles.length(always 11) but only 2 roles have active automations — the count includes "Coming soon" roles